package com.naiterui.ehp.bs.recommend.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.naiterui.ehp.bp.bo.esign.EsignNoSecretBO;
import com.naiterui.ehp.bp.bo.esign.RecomSignParamBO;
import com.naiterui.ehp.bp.constants.CommonConstant;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.utils.encypt.AESUtil;
import com.naiterui.ehp.bp.utils.lang.ConfigUtil;
import com.naiterui.ehp.bs.recommend.bean.DrMedicationRecomInfo;
import com.naiterui.ehp.bs.recommend.bean.MedicationRecom;
import com.naiterui.ehp.bs.recommend.bean.RecomPrescription;
import com.naiterui.ehp.bs.recommend.exception.ExceptionCodes;
import com.naiterui.ehp.bs.recommend.remote.IEsignFeignClient;
import com.naiterui.ehp.bs.recommend.repository.mysql.IMedicationRecomInfoRepository;
import com.naiterui.ehp.bs.recommend.repository.mysql.IMedicationRecomRepository;
import com.naiterui.ehp.bs.recommend.repository.mysql.IRecommPrescriptionRepository;
import com.naiterui.ehp.bs.recommend.service.IESignService;
import com.naiterui.ehp.bs.recommend.service.IRecomCreaterService;
import com.naiterui.ehp.bs.recommend.vo.esign.ywx.SignResultVO;

/**
 * @author guoyongxiang
 * @date 2019/9/29 10:39
 * @since 1.0.0
 */
@Service
public class ESignServiceImpl implements IESignService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ESignServiceImpl.class);

    @Autowired
    private IMedicationRecomRepository medicationRecomRepository;
    @Autowired
    private IMedicationRecomInfoRepository medicationRecomInfoRepository;
    @Autowired
    private IRecommPrescriptionRepository recommPrescriptionRepository;
    @Autowired
    private IRecomCreaterService recomCreaterService;


    @Autowired
    private IEsignFeignClient esignFeignClient;

    @Override
    public void sign(Long recomId, Long doctorId, String uniqueId, String pin, Integer requestFrom)
        throws BusinessException {
        // 查询处方ID
        MedicationRecom recom = medicationRecomRepository.get(recomId);
        DrMedicationRecomInfo recomInfo = medicationRecomInfoRepository.findFirstByRecommendId(recom.getId());
        if (recomInfo == null) {
            LOGGER.warn("处方记录缺失 recomId:{}, uniqueId:{}", recomId, uniqueId);
            throw new BusinessException(ExceptionCodes.RECOM_NOT_FOUND);
        }
        //医师签名（签名结果异步回调）
        RecomPrescription recomPrescription = recommPrescriptionRepository
            .findFirstByRecommendIdAndTypeOrderByIdDesc(recom.getId(), RecomPrescription.TYPE_UNSIGN);
        // 是否免签
        EsignNoSecretBO noSecretInfo = esignFeignClient.getNoSecretInfo(doctorId);
        if (noSecretInfo.getNoSecret()) {
            requestFrom = RecomSignParamBO.REQUEST_FROM_SYSTEM;
            pin = StringUtils.isBlank(noSecretInfo.getPin()) ? null
                : AESUtil.decrypt(CommonConstant.ESIGN_NO_SECRET_KEY, noSecretInfo.getPin());
        }
        RecomSignParamBO preSignVO = RecomSignParamBO.builder().signUserId(recomInfo.getDoctorId())
            .bizSn(recom.getSerialNumber()).uniqueId(uniqueId).createdAt(recom.getCreatedAt())
            .patientName(recomInfo.getPatientName()).patientGender(recomInfo.getPatientGender())
            .patientAge(recomInfo.getPatientAge() + recomInfo.getPatientAgeUnit())
            .pdfPath(
                ConfigUtil.getString("sys.static.resources.base.path") + recomPrescription.getPrescriptionPhotoUrl())
            .requestFrom(requestFrom).pin(pin).build();
        LOGGER.info("开始调用签名服务：preSignVO={}", preSignVO.toString());
        esignFeignClient.sign(preSignVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void signResult(SignResultVO signResultVO) throws BusinessException {
        // 查询处方ID
        MedicationRecom recom = medicationRecomRepository.findFirstBySerialNumber(signResultVO.getBizSn());
        DrMedicationRecomInfo info = medicationRecomInfoRepository.findFirstByRecommendId(recom.getId());
        if (recom == null) {
            LOGGER.warn("处方记录缺失 recomSn:{}, fileSn:{}", signResultVO.getBizSn(), signResultVO.getFileSn());
            throw new BusinessException(ExceptionCodes.RECOM_NOT_FOUND);
        }

        if (SignResultVO.USER_TYPE_DR.equals(signResultVO.getUserType())) {
            // 已签名
            if (info.getDoctorSignStatus().equals(DrMedicationRecomInfo.DOCTOR_SIGN_STATUS_DONE)
                    || info.getDoctorSignStatus().equals(DrMedicationRecomInfo.DOCTOR_SIGN_STATUS_FAIL)) {
                LOGGER.info("电子签名-重复回调-医生结果 recomSn:{}, fileSn:{}, timestamp:{}", signResultVO.getBizSn(), signResultVO.getFileSn(), signResultVO.getStatus(),
                        signResultVO.getSignTime());
                return;
            }

        } else if(SignResultVO.USER_TYPE_PH.equals(signResultVO.getUserType())){
            if (info.getPharmacistSignStatus().equals(DrMedicationRecomInfo.PHARMACIST_SIGN_STATUS_DONE)
                    || info.getPharmacistSignStatus().equals(DrMedicationRecomInfo.PHARMACIST_SIGN_STATUS_FAIL)) {
                LOGGER.info("电子签名-重复回调-药师结果 recomSn:{}, fileSn:{}, timestamp:{}", signResultVO.getBizSn(), signResultVO.getFileSn(), signResultVO.getStatus(),
                        signResultVO.getSignTime());
                return;
            }
        } else {
            if (info.getAllocatePharmacistSignStatus().equals(DrMedicationRecomInfo.AL_PHARMACIST_SIGN_STATUS_DONE)
                    || info.getAllocatePharmacistSignStatus().equals(DrMedicationRecomInfo.AL_PHARMACIST_SIGN_STATUS_FAIL)) {
                LOGGER.info("电子签名-重复回调-调配药师结果 recomSn:{}, fileSn:{}, timestamp:{}", signResultVO.getBizSn(), signResultVO.getFileSn(), signResultVO.getStatus(),
                        signResultVO.getSignTime());
                return;
            }
        }


        Integer fileType;
        if (SignResultVO.SIGN_STATUS_SUCCESS.equals(signResultVO.getStatus())) {

            if (SignResultVO.USER_TYPE_DR.equals(signResultVO.getUserType())) {
                // 医师签名文件
                fileType = RecomPrescription.TYPE_DOCTOR_SIGN;
                medicationRecomInfoRepository.updateDoctorSignStatus(DrMedicationRecomInfo.DOCTOR_SIGN_STATUS_DONE, signResultVO.getSignTime(), recom.getId());
            } else if(SignResultVO.USER_TYPE_PH.equals(signResultVO.getUserType())) {
                // 药师签名文件
                fileType = RecomPrescription.TYPE_PHARMACIST_SIGN;
                medicationRecomInfoRepository.updatePharmacistSignStatus(DrMedicationRecomInfo.PHARMACIST_SIGN_STATUS_DONE, signResultVO.getSignTime(), recom.getId());
            } else {
                // 调配药师签名文件
                fileType = RecomPrescription.TYPE_AL_PHARMACIST_SIGN;
                medicationRecomInfoRepository.updateAllocatePharmacistSignStatus(DrMedicationRecomInfo.PHARMACIST_SIGN_STATUS_DONE, signResultVO.getSignTime(), recom.getId());
            }

            recomCreaterService.savePrescriptionFile(signResultVO.getFileSn(), signResultVO.getPath(), recom.getId(), fileType);

        } else {
            LOGGER.warn("电子签名-签名失败 recomSn:{}, fileSn:{}, status:{}", signResultVO.getBizSn(), signResultVO.getFileSn(), signResultVO.getStatus());
            if (SignResultVO.USER_TYPE_DR.equals(signResultVO.getUserType())) {
                medicationRecomInfoRepository.updateDoctorSignStatus(DrMedicationRecomInfo.DOCTOR_SIGN_STATUS_FAIL, recom.getId());
            } else if(SignResultVO.USER_TYPE_PH.equals(signResultVO.getUserType())) {
                medicationRecomInfoRepository.updatePharmacistSignStatus(DrMedicationRecomInfo.PHARMACIST_SIGN_STATUS_FAIL, recom.getId());
            } else {
                medicationRecomInfoRepository.updateAllocatePharmacistSignStatus(DrMedicationRecomInfo.PHARMACIST_SIGN_STATUS_FAIL, recom.getId());
            }
        }
    }
}
